/**
 * @file database_health.h
 * @brief 数据库健康检查
 * @author liyingcheng <1871304538@qq.com>
 * @date 2025-10-12
 */

#pragma once

#include <string>
#include <chrono>
#include <nlohmann/json.hpp>

namespace cpp_backend
{
    namespace database
    {

        /**
         * @brief 数据库健康状态
         */
        enum class HealthStatus
        {
            HEALTHY,   // 健康
            DEGRADED,  // 降级（部分功能不可用）
            UNHEALTHY, // 不健康
            UNKNOWN    // 未知
        };

        /**
         * @brief 数据库健康检查结果
         */
        struct HealthCheckResult
        {
            HealthStatus status = HealthStatus::UNKNOWN;
            std::string message;
            int64_t response_time_ms = 0; // 响应时间(毫秒)
            std::chrono::system_clock::time_point timestamp;

            // 详细信息
            nlohmann::json details;

            // 转换为JSON
            nlohmann::json ToJson() const;

            // 判断是否健康
            bool IsHealthy() const { return status == HealthStatus::HEALTHY; }
        };

        /**
         * @brief MySQL健康检查结果
         */
        struct MySQLHealthResult : public HealthCheckResult
        {
            int total_connections = 0;
            int active_connections = 0;
            int idle_connections = 0;
            bool can_connect = false;
            bool can_query = false;

            // 转换为JSON
            nlohmann::json ToJson() const;
        };

        /**
         * @brief Redis健康检查结果
         */
        struct RedisHealthResult : public HealthCheckResult
        {
            int total_connections = 0;
            int active_connections = 0;
            int idle_connections = 0;
            bool can_connect = false;
            bool can_ping = false;
            std::string redis_version;
            int64_t used_memory = 0;

            // 转换为JSON
            nlohmann::json ToJson() const;
        };

        /**
         * @brief 数据库健康检查器
         */
        class DatabaseHealthChecker
        {
        public:
            /**
             * @brief 获取单例实例
             */
            static DatabaseHealthChecker &Instance();

            /**
             * @brief 检查MySQL健康状态
             * @return 健康检查结果
             */
            MySQLHealthResult CheckMySQL();

            /**
             * @brief 检查Redis健康状态
             * @return 健康检查结果
             */
            RedisHealthResult CheckRedis();

            /**
             * @brief 检查所有数据库健康状态
             * @return 总体健康检查结果
             */
            HealthCheckResult CheckAll();

            /**
             * @brief 获取健康状态字符串
             */
            static std::string StatusToString(HealthStatus status);

        private:
            DatabaseHealthChecker() = default;
            ~DatabaseHealthChecker() = default;
            DatabaseHealthChecker(const DatabaseHealthChecker &) = delete;
            DatabaseHealthChecker &operator=(const DatabaseHealthChecker &) = delete;

            /**
             * @brief 执行MySQL连接测试
             */
            bool TestMySQLConnection(int64_t &response_time_ms);

            /**
             * @brief 执行MySQL查询测试
             */
            bool TestMySQLQuery(int64_t &response_time_ms);

            /**
             * @brief 执行Redis连接测试
             */
            bool TestRedisConnection(int64_t &response_time_ms);

            /**
             * @brief 执行Redis Ping测试
             */
            bool TestRedisPing(int64_t &response_time_ms);

            /**
             * @brief 获取Redis信息
             */
            bool GetRedisInfo(std::string &version, int64_t &used_memory);
        };

    } // namespace database
} // namespace file_server
